package com.zzj.ecology.system.service.impl.system;

import com.zzj.ecology.common.constant.GlobalConstant;
import com.zzj.ecology.system.bean.system.SysMenu;
import com.zzj.ecology.system.bean.system.SysPermission;
import com.zzj.ecology.system.bean.system.SysRole;
import com.zzj.ecology.system.bean.system.SysRoleExample;
import com.zzj.ecology.system.dto.HttpResult;
import com.zzj.ecology.system.domain.Page;
import com.zzj.ecology.system.mapper.system.SysMenuMapper;
import com.zzj.ecology.system.mapper.system.SysPermissionMapper;
import com.zzj.ecology.system.mapper.system.SysRoleMapper;
import com.zzj.ecology.system.service.system.SysRoleService;
import com.zzj.ecology.system.utils.AppUtils;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;

@Service("sysRoleService")
@Transactional(rollbackFor = Exception.class)
@Slf4j
public class SysRoleServiceImpl implements SysRoleService {

    public static final Logger logger = LoggerFactory.getLogger(SysRoleServiceImpl.class);

    @Autowired
    private SysRoleMapper sysRoleMapper;
    @Autowired
    private SysMenuMapper sysMenuMapper;
    @Autowired
    private SysPermissionMapper sysPermissionMapper;


    /**
     * 根据用户主键查询用户的角色权限
     * @param userid
     * @return
     */
    public List<SysRole> findRolesByUserId(Integer userid) {
        List<SysRole> list = sysRoleMapper.findRolesByUserId(userid);
        return list;
    }

    /**
     * 分页查询 角色 数据
     * @param page
     * @return
     */
    public HttpResult findPageList(Page page) {
        int currentPage = page.getCurrentPage();
        Integer pageCounts = page.getPageCounts();
        int first = (currentPage - 1) * pageCounts;

        List<SysRole> lists = sysRoleMapper.findPageList(first, pageCounts);
        page.getData().put(HttpResult.LIST_TAG, lists);// 当前页面数据

        SysRoleExample example = new SysRoleExample();
        SysRoleExample.Criteria criteria = example.createCriteria();
        criteria.andDeleteStatusEqualTo(GlobalConstant.DELETE_STATUS_NOT_DELETE);//delete_status='0' 的数据

        List<SysRole> list1 = sysRoleMapper.selectByExample(example);//不分页总数据
        page.setTotalCounts(list1.size());
        return HttpResult.success().add(HttpResult.PAGE_TAG, page);
    }

    /**
     * 查询 穿梭框 用数据
     * layui transfer
     * @param userId
     * @return
     */
    public HttpResult findTransferList(Integer userId) {
        SysRoleExample example = new SysRoleExample();
        example.createCriteria().andDeleteStatusEqualTo(GlobalConstant.DELETE_STATUS_NOT_DELETE);
        List<SysRole> parList = sysRoleMapper.selectByExample(example);
        List<SysRole> subList = sysRoleMapper.findRolesByUserId(userId);
        return HttpResult.success().add(HttpResult.PAR_LIST_TAG, parList).add(HttpResult.SUB_LIST_TAG,subList);
    }

    /**
     * 新角色创建, 创建角色基本信息,并赋予基本菜单功能
     * @param sysRole
     * @return
     */
    public int createAndInitializeMenuAndBuildPermissionRelation(SysRole sysRole) {
        //给角色创建基本菜单功能, sys_role_menu
        //...
        return sysRoleMapper.insertSelective(sysRole);
    }

    /**
     * 查询 roleCode 角色别名是否已经存在。如果存在返回 true， 如果不存在返回 false
     * @param roleCode 角色别名
     * @return
     */
    public boolean checkRoleCodeExist(String roleCode) {
        SysRoleExample example = new SysRoleExample();
        example.createCriteria().andDeleteStatusEqualTo(GlobalConstant.DELETE_STATUS_NOT_DELETE)
                .andRoleCodeEqualTo(roleCode);
        List<SysRole> roles = sysRoleMapper.selectByExample(example);
        return roles.size() > 0 ? true : false;
    }

    /**
     * 删除角色操作, 标记删除 标记 delete_status = '1' 表示删除,并更新用户的修改时间及修改人字段
     * @param roleids
     * @param username
     * @return
     */
    public HttpResult updateDeleteStatusByIds(List<Integer> roleids, String username) {
        int i = sysRoleMapper.updateDeleteStatusByIds(roleids, username, GlobalConstant.DELETE_STATUS_DELETE);
        return HttpResult.success();
    }

    /**
     * 修改角色基本信息,如果角色名称(角色代码不可修改),备注信息,系统自动获取到当前登录人员作为 修改人员和记录修改时间
     * @param sysRole
     * @return
     */
    public HttpResult update(SysRole sysRole) {
        sysRoleMapper.updateByPrimaryKeySelective(sysRole);
        return HttpResult.success();
    }

    /**
     * 给当前角色 重新 分配相应的菜单, 为防止出错，使用了同步
     * @param sysRole
     * @param menuIds
     * @return
     */
    public synchronized HttpResult reBuildRoleMenuRelation(SysRole sysRole, List<Integer> menuIds) {
        Integer roleId = sysRole.getRoleId();
        List<SysMenu> menus = sysMenuMapper.findRoleMenuRelationByRoleId(roleId);
        if (menus.size() > 0) {
            sysMenuMapper.deleteRoleMenuRelationByRoleId(roleId);
        }
        sysMenuMapper.insertRoleMenuRelation(roleId, menuIds);
        // 根据 roleId 查询出 与此 Role 关联的 Permission sys_role_permission 并将其删除，重新建立
        List<SysPermission> permissions = sysPermissionMapper.findRolePermissionRelationByRoleId(roleId);
        if (permissions.size() > 0) {
            sysPermissionMapper.deleteRolePermissionRelationByRoleId(roleId);
        }
        List<Integer> permsids = findPermissionIdsByMenuIds(menuIds);
        if (permsids.size() > 0) {
            sysPermissionMapper.insertRolePermissionRelation(roleId, permsids);
        }
        updateUpdateAtAndUpdateByByRoleId(roleId, sysRole.getUpdateAt(), sysRole.getUpdateBy());//更新 SysRole 中的 update_at update_by 字段
        return HttpResult.success();
    }



    /**
     * 查询指定 角色 的所有菜单 ,根据 角色ID 查询(用于数据回显选中的数据)
     * @param roleId
     * @return
     */
    public HttpResult findMenusByRoleId(Integer roleId) {
        List<SysMenu> menus = sysMenuMapper.findRoleMenuRelationByRoleId(roleId);
        HttpResult result = HttpResult.success();
        String idsStr = AppUtils.createMenuIds2String(menus);
        result.setData(idsStr);
        return result.add(HttpResult.DATA_TAG, menus);
    }

    private List<Integer> findPermissionIdsByMenuIds(List<Integer> menuIds) {
        //List<Integer> list = new ArrayList<>();
        List<Integer> list = sysPermissionMapper.findPermissionIdsByMenuIds(menuIds);
        return list;
    }

    private void updateUpdateAtAndUpdateByByRoleId(Integer roleId, Date updateAt, String updateBy) {
        sysRoleMapper.updateUpdateAtAndUpdateByByRoleId(roleId, updateAt, updateBy);
    }


}
